package com.wwy.hkapi.HKApi.callBack;

import com.sun.jna.Pointer;
import com.sun.jna.ptr.ByteByReference;
import com.wwy.hkapi.HKApi.HCNetSDK;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.*;

import java.awt.image.BufferedImage;
import java.io.*;
import java.text.SimpleDateFormat;

/**
 * 视频预览回调
 * @Author: wwy
 * @Date: 2022/6/14 14:49
 */
public class MyRealDataCallBack_V30 implements HCNetSDK.FRealDataCallBack_V30 {
    private PipedInputStream pipedInputStream = new PipedInputStream();
    private PipedOutputStream pipedOutputStream = new PipedOutputStream();
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    /**
     * 解码器
     */
    private FFmpegFrameGrabber grabber = null;
    /**
     * 编码器
     */
    private FFmpegFrameRecorder record = null;
    public MyRealDataCallBack_V30(){
        try {
            pipedInputStream.connect(pipedOutputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            try {


                grabber = new FFmpegFrameGrabber(pipedInputStream,0);
                grabber.setOption("rtsp_transport", "tcp");
                grabber.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
                grabber.setVideoCodec(avcodec.AV_CODEC_ID_H264);
                grabber.setAudioStream(Integer.MIN_VALUE);
                long stime = System.currentTimeMillis();
                // 检测回调函数书否有数据流产生，防止avformat_open_input函数阻塞
                int availableValue = 0;
                do {
                    Thread.sleep(100);
                    System.out.println("availableValue值"+availableValue);
                    if (System.currentTimeMillis() - stime > 20000) {
                        System.out.println("-----SDK回调无视频流产生------");
                        return;
                    }
                } while ((availableValue = pipedInputStream.available()) != 1024);
                grabber.start();
                long startTime = System.currentTimeMillis();
                record = new FFmpegFrameRecorder("http://localhost:10010/upload/test.m3u8",grabber.getImageWidth(),grabber.getImageHeight(),0);
                /*//视频帧率
                record.setFrameRate(grabber.getFrameRate());
                //编码
                record.setVideoCodec(avcodec.AV_CODEC_ID_H264);
                record.setFormat("mp4");*/
                record.setFormat("hls");
                record.setOption("hls_time", "5");
                record.setOption("hls_list_size", "0");
                record.setOption("hls_flags", "delete_segments");
                record.setOption("hls_delete_threshold", "1");
                record.setOption("hls_segment_type", "mpegts");
                record.setOption("hls_segment_filename", "http://localhost:10010/upload/test-%d.ts");
                //record.setOption("hls_key_info_file", "http://localhost:8080/preview/");

                // http属性
                record.setOption("method", "POST");

                record.setFrameRate(25);
                record.setGopSize(2 * 25);
                record.setVideoQuality(1.0);
                record.setVideoBitrate(10 * 1024);
                record.setVideoCodec(avcodec.AV_CODEC_ID_H264);
                record.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
                record.start();

                Frame frame;
                /*while (((System.currentTimeMillis()-startTime) <=30000) &&(frame=grabber.grab()) != null){
                    if(frame.image != null){
                        record.record(frame);
                    }
                }*/
                while ((frame=grabber.grab()) != null){
                    if(frame.image != null){
                        record.record(frame);
                    }
                }
                System.out.println("执行结束");
                grabber.stop();
                record.stop();
            } catch (FrameRecorder.Exception e) {
                e.printStackTrace();
            } catch (FrameGrabber.Exception e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }).start();
    }
    @Override
    public void invoke(int lRealHandle, int dwDataType, ByteByReference pBuffer, int dwBufSize, Pointer pUser) {
        switch (dwDataType)
        {
            case HCNetSDK.NET_DVR_SYSHEAD: //系统头
                break;
            //m_iPort = lPort; //第一次回调的是系统头，将获取的播放库port号赋值给全局port，下次回调数据时即使用此port号播放
            case HCNetSDK.NET_DVR_STREAMDATA:   //码流数据
                byte[] byteArray = pBuffer.getPointer().getByteArray(0, dwBufSize);
                try {
                    pipedOutputStream.write(byteArray);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            default:

        }

    }
}
